﻿#include "tcpserverdemo.h"
#include <QDateTime>
#include <QtDebug>
#include <net/netwriting.h>
#include <net/tcpserver.h>
#include <net/tcpsession.h>
#include <QtCore/QMetaEnum>

using namespace QtSocket;

TcpServerDemo::TcpServerDemo(QObject *parent) : QObject(parent)
{
    m_server = Q_NULLPTR;
    m_timerID = 0;
    m_counter = 0;

    connect(this, &TcpServerDemo::stop_signal, this, &TcpServerDemo::stop_slot);
}

TcpServerDemo::~TcpServerDemo()
{
    if(m_server)
    {
        m_server->deleteLater();
        m_server = Q_NULLPTR;
    }
}

bool TcpServerDemo::start(QHostAddress localAddress, int port)
{
    if(m_server)
    {
        return false;
    }

    m_timerID = startTimer(5000);
    m_server = new TcpServer(this);
    bool ok = m_server ->listen(localAddress, quint16(port));
    if(!ok)
    {
        m_server->deleteLater();
        m_server = Q_NULLPTR;
    }
    return ok;
}

void TcpServerDemo::stop()
{
    emit stop_signal();
}

void TcpServerDemo::onError(QAbstractSocket::SocketError error)
{
    QString msg;
    QTextStream stream(&msg);
    QMetaEnum metaEnum = QMetaEnum::fromType<QAbstractSocket::SocketError>();
    //枚举值转字符串
    stream << tr("Server 检测到socket错误信息：") << metaEnum.valueToKey(error);
    emit log_signal(msg);
}

void TcpServerDemo::onStateChanged(TcpSession *session, bool connected)
{
    QString msg ;
    QTextStream stream;
    stream.setString(&msg);
    if(connected )
    {
        session->setReading(new Reading(session, this));
        stream << tr(" Session 连接成功！远端地址：") << session->remoteIp().toString() << ":" << session->remotePort();

    }else {
        NetReading *reading = session->reading();
        delete reading;
        stream << tr("Remote 断开连接，地址：") << session->remoteIp().toString() << ":" << session->remotePort() ;
    }
    emit log_signal(msg);
}

void TcpServerDemo::fulfil(QSharedPointer<QtSocket::NetWriting> sender, int size)
{
    int packSize = sender->data().size();
    m_counter.fetchAndAddAcquire(-packSize);

    QString msg ;
    QTextStream stream;
    stream.setString(&msg);
    stream << tr("写入数据长度：") << size ;
    emit log_signal(msg);

    sender->deleteLater();

}

void TcpServerDemo::stop_slot()
{
    if(m_server)
    {
        if(m_timerID != -1)
        {
            killTimer(m_timerID);
            m_timerID = -1;
        }

        QList<TcpSession *> lst = m_server->sessionList();
        foreach(TcpSession *session, lst)
        {
            NetReading *reading = session->reading();
            if(reading)
            {
                session->setReading(Q_NULLPTR);
                delete reading;
            }
        }
        m_server->deleteLater();
        m_server = Q_NULLPTR;
    }
}

void TcpServerDemo::timerEvent(QTimerEvent *event)
{
    if(event->timerId() != m_timerID)
    {
        return;
    }
    if(m_server == Q_NULLPTR)
    {
        return;
    }
    QString info = QDateTime::currentDateTime().toString();
    QByteArray array = info.toUtf8();

    static int id = -1;
    if(id == -1)
    {
        id = qRegisterMetaType<QSharedPointer<NetWriting>>("QSharedPointer<NetWriting>");
    }
    // 遍历会话，写入数据。
    QList<TcpSession *> lst = m_server->sessionList();
    foreach(TcpSession *session, lst)
    {
        QSharedPointer<NetWriting> writing(new NetWriting(array, this), &QObject::deleteLater);
        connect(writing.data(), &NetWriting::fulfil, this, &TcpServerDemo::fulfil);

        int writeSize = array.size();
        m_counter.fetchAndAddOrdered(writeSize);
        QString msg ;
        QTextStream stream;
        stream.setString(&msg);
        stream << tr("写入") << session->remoteIp().toString() << ":" << session->remotePort();
        if(session->write(writing) == false)
        {
            m_counter.fetchAndAddOrdered(-writeSize);
            stream << tr("失败。");
        }else {
            stream << tr("成功！");
        }
        emit log_signal(msg);
        qDebug() << msg;
    }
}

TcpServerDemo::Reading::Reading(TcpSession *ownerSession, TcpServerDemo *ownerTest)
{
    m_ownerSession = ownerSession;
    m_ownerTest = ownerTest;
}

void TcpServerDemo::Reading::onProc(const QByteArray &arry)
{
    QString msg ;
    QTextStream stream;
    stream.setString(&msg);
    stream << tr("接收到") <<
              m_ownerSession->remoteIp().toString() << ":" <<
              m_ownerSession->remotePort()<<
              tr("数据:") << arry;
    emit m_ownerTest->log_signal(msg);

    qDebug() << msg;
}
